package com.yue.test.test2;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewGroup;

import androidx.core.widget.NestedScrollView;

import java.lang.reflect.Field;

/**
 * TODO: document your custom view class.
 */
public class MeNestedScrollView2 extends NestedScrollView {

    private String TAG = "shimyTest2";

    //动画时长
    private int animDuration = 400;
    // 屏幕的宽高
    int screenWidth;
    int screenHeight;

    //缩放倍数，扩大为原来的1.2倍
    private float scaleX = 1.4f;//使用scale缩放动画
    private float scaleY = 0.7f;//改变实际View的高度，以使得和下方的View自动贴合

    /**
     * banner当前的状态
     */
    public enum BannerCurState {
        BIG,//放大状态
        NORMAL,//正常状态
    }

    //正在执行变大或恢复正常的动画，动画执行期间不能做任何操作（另一动画或滚动事件）
    private boolean isAniming = false;

    //默认刚进来时是放大的状态
    private BannerCurState bannerCurState = BannerCurState.BIG;

    // 要执行缩放的View
    private ViewGroup bannerView;

    private VelocityTracker mVelocityTracker;

    private Field mLastMotionYField;

    public MeNestedScrollView2(Context context) {
        super(context);
        init(null, 0);
    }

    public MeNestedScrollView2(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs, 0);
    }

    public MeNestedScrollView2(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs, defStyle);
    }

    private void init(AttributeSet attrs, int defStyle) {
        mVelocityTracker = VelocityTracker.obtain();
        screenWidth = getResources().getDisplayMetrics().widthPixels;
        screenHeight = getResources().getDisplayMetrics().heightPixels;
//        getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
//            @Override
//            public void onGlobalLayout() {
//                if (bannerView == null) {
//                    bannerView = findViewById(R.id.fl_ad);
//                    bannerBig();
//                }
//            }
//        });
        try {
            mLastMotionYField = getClass().getSuperclass().getDeclaredField("mLastMotionY");
            Log.d(TAG, "init: " + mLastMotionYField.toString());
            mLastMotionYField.setAccessible(true);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

    }


    /**
     * 设置缩放View
     *
     * @param bannerView
     */
    public void setBannerView(ViewGroup bannerView) {
        this.bannerView = bannerView;
        bannerBig();
    }

    public void outNoticeBig() {
        isAniming = true;
        //先改变状态，防止重复执行动画
        bannerCurState = BannerCurState.BIG;
        bannerBig();
    }

    public void outNoticeRestore() {
        isAniming = true;
        bannerCurState = BannerCurState.NORMAL;
        bannerRestore();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
//        mVelocityTracker.addMovement(ev);
//        mVelocityTracker.computeCurrentVelocity(1000);
//        float yVelocity = mVelocityTracker.getYVelocity();
//        float xVelocity = mVelocityTracker.getXVelocity();
//
//        if (Math.abs(yVelocity) < Math.abs(xVelocity)) {
//            mVelocityTracker.clear();
//            //不拦截左右滑动
//            return super.onInterceptTouchEvent(ev);
//        }
//        //拦住向下滚动的移动事件，让里面的RecyclerView接收不到滚动事件；
//        // 左右移动不拦截
////        if (ev.getAction() == MotionEvent.ACTION_MOVE && getScrollY() < getResources().getDisplayMetrics().heightPixels) {
////            return true;
////        }
//        mVelocityTracker.clear();
        return super.onInterceptTouchEvent(ev);
    }

    //根据IOS效果展示，放大效果根据SmartLayout来，先刷新，稍后执行个放大动画即可，此处不再监听向下的手势
    @Override
    public boolean onTouchEvent(MotionEvent ev) {

        // 当scrollY==0时，不处理任何事件，此时ScrollView是无法滚动的，需要开始放大和缩小的动画
        /*
         * 滚动到顶部了scrollY==0-10之间（scrollY(0,0)），才需要执行扩大或缩小动画；
         * 此时需要将ScrollView的滚动给禁止掉，通过让ScrollView中的子布局（Container）来接收事件（内部拦截或外部拦截）
         * 执行完动画恢复ScrollView的滚动
         * 1. 当向上滚动 且当前是big状态显示 则执行缩小动画，small状态不做任何处理，向下滚动则不做处理
         * 2. 当向下滚动 且当前是small显示状态 则执行放大动画，big状态不做任何处理，向上滚动则不做任何处理
         *
         * */
        int scrollY = getScrollY();
        mVelocityTracker.addMovement(ev);
        //参数初始化或复原
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            //如果我们不接收down事件，后面又没有子View消费down事件的话，则后续事件永远也不会进来了
            return super.onTouchEvent(ev);
        }

        if (isAniming) {
            //正在执行动画，return false 不处理任何事件
            return false;
        }

        if (scrollY == 0 && ev.getAction() == MotionEvent.ACTION_MOVE) {
            mVelocityTracker.computeCurrentVelocity(1000);
            float yVelocity = mVelocityTracker.getYVelocity();
            if (yVelocity >= 0) {
                Log.d(TAG, "onTouchEvent yVelocity: "+yVelocity);
                //向下滚动 -- 放大
                if (bannerCurState != BannerCurState.BIG) {
//                    isAniming = true;
//                    //先改变状态，防止重复执行动画
//                    bannerCurState = BannerCurState.BIG;
//                    bannerBig();
                    return super.onTouchEvent(ev);
                } else {
                    return super.onTouchEvent(ev);
                }

            } else if (yVelocity < 0) {
                Log.d(TAG, "onTouchEvent yVelocity: "+yVelocity);
                //向上滚动 --> 复原
                if (bannerCurState != BannerCurState.NORMAL) {
                    isAniming = true;
                    bannerCurState = BannerCurState.NORMAL;
                    bannerRestore();
                } else {
                    try {
                        //由于我们接管了一段事件Move，所以父类中的一些在Move中设置的属性无法获得
                        //在这里反射获取，并设置一下，防止出现滚动错误
                        mLastMotionYField.setInt(this, (int) ev.getY());
                        setScrollY(1);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                    return super.onTouchEvent(ev);
                }
            }
            mVelocityTracker.clear();
            return false;
        }
        mVelocityTracker.clear();
        return super.onTouchEvent(ev);
    }

    /**
     * View的实际大小变化--其实是高度
     */
    private void bannerWHChange(float scaleSize) {
        int width = screenWidth;
        int height = (int) (screenHeight * scaleSize);
        LayoutParams params = new LayoutParams(width, height);
        bannerView.setLayoutParams(params);
    }


    /**
     * banner复原到正常的大小
     */
    private void bannerRestore() {
        /*--------------X轴的渐变动画--------------*/
        ValueAnimator animatorX = ValueAnimator.ofFloat(scaleX, 1.0f);
        animatorX.addUpdateListener(animation -> {
            float scaleValue = (float) animation.getAnimatedValue();
            /** 此缩放以1为基准点：1=不缩放，先用缩放做，不过后面得用LayoutParams改变View的实际大小才行 */
            bannerView.setScaleX(scaleValue);
            bannerWHChange(scaleValue);
        });

        /*---------------------Y轴的渐变动画-------------------------*/
        ValueAnimator animatorY = ValueAnimator.ofFloat(1.0f, scaleY);
        final float[] oldTime = {0};
        animatorY.addUpdateListener(animation -> {
            float scaleValue = (float) animation.getAnimatedValue();
            bannerWHChange(scaleValue);
//            if (oldTime[0] == 0) {
//                oldTime[0] = animation.getCurrentPlayTime();
//            }
//            Log.d(TAG, "bannerRestore: "+(animation.getCurrentPlayTime()-oldTime[0]));
//            if ((animation.getCurrentPlayTime() -oldTime[0])>460){
//                isAniming = false;
//            }
        });

        /*X轴 和 Y轴的动画一起播放*/
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(animatorX, animatorY);
        animatorSet.setDuration(animDuration);
        //添加动画结束时的监听
        animatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                isAniming = false;
                Log.d(TAG, "onAnimationEnd: ");
            }
        });
        animatorSet.start();
    }


    /**
     * banner变大
     */
    private void bannerBig() {
        /*---------------X轴的渐变动画---------------------*/
        ValueAnimator animatorX = ValueAnimator.ofFloat(1.0f, scaleX);
        animatorX.addUpdateListener(animation -> {
            float scaleValue = (float) animation.getAnimatedValue();
            /** 此缩放以1为基准点：1=不缩放, 先用缩放做，不过后面得用LayoutParams改变View的实际大小才行 */
            bannerView.setScaleX(scaleValue);
//            mBinding.flAd.setScaleY(scaleValue);
            bannerWHChange(scaleValue);
        });

        /*---------------------Y轴的渐变动画-------------------------*/
        ValueAnimator animatorY = ValueAnimator.ofFloat(scaleY, 1.0f);
        animatorY.addUpdateListener(animation -> {
            float scaleValue = (float) animation.getAnimatedValue();
            bannerWHChange(scaleValue);
        });
        /*X轴 和 Y轴的动画一起播放*/
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(animatorX, animatorY);
        animatorSet.setDuration(animDuration);
        //添加动画结束时的监听
        animatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                isAniming = false;
            }
        });
        animatorSet.start();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        mVelocityTracker.recycle();
    }

    public BannerCurState getBannerCurState() {
        return bannerCurState;
    }
}